# -*- coding: utf-8 -*-
"""
缓存管理模块

提供系统配置的缓存功能，支持内存缓存和Redis缓存
"""

import json
import hashlib
from typing import Any, Optional, Dict, List
from datetime import datetime, timedelta


class MemoryCacheManager:
    """内存缓存管理器"""
    
    def __init__(self):
        self._cache: Dict[str, Dict[str, Any]] = {}
        self._expiry: Dict[str, datetime] = {}
    
    def get(self, key: str) -> Optional[Any]:
        """获取缓存值"""
        if key not in self._cache:
            return None
            
        # 检查是否过期
        if key in self._expiry and datetime.now() > self._expiry[key]:
            self.delete(key)
            return None
            
        return self._cache[key].get('value')
    
    def set(self, key: str, value: Any, expiry_seconds: int = 3600) -> bool:
        """设置缓存值"""
        try:
            self._cache[key] = {
                'value': value,
                'created_at': datetime.now()
            }
            
            if expiry_seconds > 0:
                self._expiry[key] = datetime.now() + timedelta(seconds=expiry_seconds)
            
            return True
        except Exception:
            return False
    
    def delete(self, key: str) -> bool:
        """删除缓存"""
        try:
            if key in self._cache:
                del self._cache[key]
            if key in self._expiry:
                del self._expiry[key]
            return True
        except Exception:
            return False
    
    def delete_pattern(self, pattern: str) -> int:
        """删除匹配模式的缓存"""
        deleted_count = 0
        keys_to_delete = []
        
        for key in self._cache.keys():
            if pattern.replace('*', '') in key:
                keys_to_delete.append(key)
        
        for key in keys_to_delete:
            if self.delete(key):
                deleted_count += 1
                
        return deleted_count
    
    def clear(self) -> bool:
        """清空所有缓存"""
        try:
            self._cache.clear()
            self._expiry.clear()
            return True
        except Exception:
            return False
    
    def keys(self, pattern: str = "*") -> List[str]:
        """获取匹配模式的所有键"""
        if pattern == "*":
            return list(self._cache.keys())
        
        return [key for key in self._cache.keys() if pattern.replace('*', '') in key]
    
    def info(self) -> Dict[str, Any]:
        """获取缓存统计信息"""
        now = datetime.now()
        expired_count = sum(1 for exp_time in self._expiry.values() if now > exp_time)
        
        return {
            "type": "memory",
            "total_keys": len(self._cache),
            "expired_keys": expired_count,
            "valid_keys": len(self._cache) - expired_count,
            "memory_usage": "N/A"
        }


class RedisCacheManager:
    """Redis缓存管理器（需要redis库）"""
    
    def __init__(self, redis_url: str = "redis://localhost:6379/0"):
        self.redis_url = redis_url
        self._redis = None
        self._connect()
    
    def _connect(self):
        """连接Redis"""
        try:
            import redis
            self._redis = redis.from_url(self.redis_url, decode_responses=True)
            # 测试连接
            self._redis.ping()
        except ImportError:
            raise ImportError("需要安装redis库: pip install redis")
        except Exception as e:
            raise ConnectionError(f"Redis连接失败: {str(e)}")
    
    def get(self, key: str) -> Optional[Any]:
        """获取缓存值"""
        try:
            value = self._redis.get(key)
            if value is None:
                return None
            
            # 尝试JSON解析
            try:
                return json.loads(value)
            except json.JSONDecodeError:
                return value
        except Exception:
            return None
    
    def set(self, key: str, value: Any, expiry_seconds: int = 3600) -> bool:
        """设置缓存值"""
        try:
            # JSON序列化
            if isinstance(value, (dict, list)):
                serialized_value = json.dumps(value, ensure_ascii=False)
            else:
                serialized_value = str(value)
            
            if expiry_seconds > 0:
                return self._redis.setex(key, expiry_seconds, serialized_value)
            else:
                return self._redis.set(key, serialized_value)
        except Exception:
            return False
    
    def delete(self, key: str) -> bool:
        """删除缓存"""
        try:
            return bool(self._redis.delete(key))
        except Exception:
            return False
    
    def delete_pattern(self, pattern: str) -> int:
        """删除匹配模式的缓存"""
        try:
            keys = self._redis.keys(pattern)
            if keys:
                return self._redis.delete(*keys)
            return 0
        except Exception:
            return 0
    
    def clear(self) -> bool:
        """清空所有缓存"""
        try:
            return self._redis.flushdb()
        except Exception:
            return False
    
    def keys(self, pattern: str = "*") -> List[str]:
        """获取匹配模式的所有键"""
        try:
            return self._redis.keys(pattern)
        except Exception:
            return []
    
    def info(self) -> Dict[str, Any]:
        """获取缓存统计信息"""
        try:
            info = self._redis.info()
            return {
                "type": "redis",
                "total_keys": info.get("db0", {}).get("keys", 0),
                "expired_keys": info.get("expired_keys", 0),
                "memory_usage": info.get("used_memory_human", "N/A"),
                "connected_clients": info.get("connected_clients", 0)
            }
        except Exception:
            return {"type": "redis", "error": "无法获取Redis信息"}


class CacheManager:
    """统一缓存管理器"""
    
    def __init__(self, cache_type: str = "memory", redis_url: str = None):
        self.cache_type = cache_type
        
        if cache_type == "redis" and redis_url:
            try:
                self._cache = RedisCacheManager(redis_url)
            except (ImportError, ConnectionError):
                # 如果Redis不可用，降级到内存缓存
                print("Redis不可用，降级到内存缓存")
                self._cache = MemoryCacheManager()
                self.cache_type = "memory"
        else:
            self._cache = MemoryCacheManager()
            self.cache_type = "memory"
    
    def get(self, key: str) -> Optional[Any]:
        """获取缓存值"""
        return self._cache.get(key)
    
    def set(self, key: str, value: Any, expiry_seconds: int = 3600) -> bool:
        """设置缓存值"""
        return self._cache.set(key, value, expiry_seconds)
    
    def delete(self, key: str) -> bool:
        """删除缓存"""
        return self._cache.delete(key)
    
    def delete_pattern(self, pattern: str) -> int:
        """删除匹配模式的缓存"""
        return self._cache.delete_pattern(pattern)
    
    def clear(self) -> bool:
        """清空所有缓存"""
        return self._cache.clear()
    
    def keys(self, pattern: str = "*") -> List[str]:
        """获取匹配模式的所有键"""
        return self._cache.keys(pattern)
    
    def info(self) -> Dict[str, Any]:
        """获取缓存统计信息"""
        info = self._cache.info()
        info["cache_type"] = self.cache_type
        return info
    
    def health_check(self) -> Dict[str, Any]:
        """健康检查"""
        try:
            test_key = "__cache_health_check__"
            test_value = "ok"
            
            # 测试设置和获取
            set_success = self.set(test_key, test_value, 60)
            if not set_success:
                return {"healthy": False, "error": "无法设置缓存"}
            
            get_value = self.get(test_key)
            if get_value != test_value:
                return {"healthy": False, "error": "缓存值不匹配"}
            
            # 清理测试数据
            self.delete(test_key)
            
            return {
                "healthy": True,
                "cache_type": self.cache_type,
                "info": self.info()
            }
        except Exception as e:
            return {"healthy": False, "error": str(e)}


# 全局缓存管理器实例
cache_manager = CacheManager()


def init_cache(cache_type: str = "memory", redis_url: str = None):
    """初始化缓存管理器"""
    global cache_manager
    cache_manager = CacheManager(cache_type, redis_url)
    return cache_manager


def get_cache_manager() -> CacheManager:
    """获取缓存管理器实例"""
    return cache_manager